<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Test Page for geoPolygonUtils.geometry.Vector class</title>
  <script language="JavaScript" type="text/javascript"
      src="../tools/jsunit/app/jsUnitCore.js"></script>
  <script language="JavaScript" type="text/javascript"
      src="test-utils.js"></script>
  <script language="JavaScript" type="text/javascript"
      src="../src/geometry.js"></script>
  <script language="JavaScript" type="text/javascript">

    // Alias for the Vector class.
    var Vector = geoPolygonUtils.geometry.Vector;

    
    function testVectorConstructor() {
      var v = new Vector(312.43, -4.67);
      assertVectorCoords(312.43, -4.67, v);
    };

    
    function testFromPolar() {
      var v = Vector.fromPolar(0, 6);
      assertVectorCoords(6, 0, v);
      
      v = Vector.fromPolar(Math.PI, 3.45);
      assertVectorCoords(-3.45, 0, v);
      
      v = Vector.fromPolar(2 * Math.PI, 12.31);
      assertVectorCoords(12.31, 0, v);
            
      v = Vector.fromPolar(Math.PI * 0.5, 666.573);
      assertVectorCoords(0, 666.573, v);

      v = Vector.fromPolar(Math.PI * 1.25, 5.6);
      assertVectorCoords(- 5.6 * 0.5 * Math.sqrt(2),
                         - 5.6 * 0.5 * Math.sqrt(2), v);

      v = Vector.fromPolar(- Math.PI / 3, 11.7);
      assertVectorCoords(11.7 * 0.5, - 11.7 * 0.5 * Math.sqrt(3), v);
    };

    
    function testMultiply() {
      var v = new Vector(3.3, -5.5);
      var u = v.multiply(-0.4);
      
      assertVectorCoords(-1.32, 2.2, u);
      
      u = v.multiply(0);
      assertVectorCoords(0, 0, u);
      assertVectorCoords('\'multiply\' shouldn\'t change original vector',
                         3.3, -5.5, v);
    };
    
    
    function testPlus() {
      var v = new Vector(-4, 1);
      var u = new Vector(5, -2);
      
      var p = v.plus(u);

      assertVectorCoords(1, -1, p); 
      assertVectorCoords('\'plus\' shouldn\'t change original vectors',
                         -4, 1, v);
      assertVectorCoords('\'plus\' shouldn\'t change original vectors',
                         5, -2, u);
    };
    
    
    function testMinus() {
      var v = new Vector(-4, 1);
      var u = new Vector(5, -2);
      
      var p = v.minus(u);

      assertVectorCoords(-9, 3, p); 
      assertVectorCoords('\'minus\' shouldn\'t change original vectors',
                         -4, 1, v);
      assertVectorCoords('\'minus\' shouldn\'t change original vectors',
                         5, -2, u);
    };
    
    
    function testDotProduct() {
      assertAlmostEquals(
          -22, new Vector(-4, 1).dotProduct(new Vector(5, -2)));
      assertAlmostEquals('dot product of orthogonal vectors',
          0, new Vector(-4, 1).dotProduct(new Vector(1, 4)));
      assertAlmostEquals('dot product of a vector with itself',
          25, new Vector(-3, 4).dotProduct(new Vector(-3, 4)));
    };
    
    
    function testCrossProduct() {
      assertAlmostEquals(
          3, new Vector(-4, 1).crossProduct(new Vector(5, -2)));
      assertAlmostEquals('cross product of a vector with itself',
          0, new Vector(1, 4).crossProduct(new Vector(1, 4)));
      assertAlmostEquals('cross product of orthogonal vectors',
          -25, new Vector(-3, 4).crossProduct(new Vector(4, 3)));
    };
    
    
    function testOrtho() {
      var v = new Vector(5.32, -11.47).ortho();
      assertVectorCoords(11.47, 5.32, v);
    };
    
    
    function testIsZero() {
      var v = new Vector(0, 0);
      assertTrue(v.isZero());
      
      v = new Vector(1.5324e-14, -2.635e-15);
      assertTrue('vectors close to zero should be considered zero vectors',
                 v.isZero());
      
      v = new Vector(-0.1, -0.01);
      assertFalse(v.isZero());
      assertTrue('isZero check with modified precision', v.isZero(0.5));
      var precision = new geoPolygonUtils.geometry.Precision(1e-9, 0.5, 1e-9);
      assertTrue('isZero check using custom Precision object',
                 v.isZero(precision));
    };
    
    
    function testAngle() {
      var v = new Vector(-3.45, 0);
      assertAlmostEquals(Math.PI, v.angle());

      v = new Vector(3.45, 0);
      assertAlmostEquals(0, v.angle());
      
      v = new Vector(0, -12.31);
      assertAlmostEquals(Math.PI * 1.5, v.angle());
      
      v = new Vector(11.7 * 0.5, - 11.7 * 0.5 * Math.sqrt(3));
      assertAlmostEquals(Math.PI * 5 / 3, v.angle());
      
      v = new Vector(1.5324e-14, -2.635e-15);
      assertNull('angle is not returned for zero vectors', v.angle());
    };
    
    
    function testNorm() {
      var v = new Vector(0, -11);
      assertAlmostEquals(11, v.norm());

      v = new Vector(-30, 40);
      assertAlmostEquals(50, v.norm());
    };
    
    
    function testNorm2() {
      var v = new Vector(-11, 0);
      assertAlmostEquals(121, v.norm2());

      v = new Vector(-30, 40);
      assertAlmostEquals(2500, v.norm2());
    };

    
    
    function testNormalized() {
      var v = new Vector(-11, 0);
      var u = v.normalized();
      assertVectorCoords(-1, 0, u);
      assertVectorCoords('\'normalized\' shouldn\'t change original vector',
                         -11, 0, v);

      v = new Vector(-30, 40);
      u = v.normalized();
      assertVectorCoords(-0.6, 0.8, u);
      assertVectorCoords('\'normalized\' shouldn\'t change original vector',
                         -30, 40, v);
      
      v = new Vector(1.5324e-14, -2.635e-15);
      assertNull('normalized vector is not returned for zero vectors',
                 v.normalized());
    };
    
    
    function testDistanceToPoint() {
      var v = new Vector(-11, 0);
      var u = new Vector(2, 0);
      assertAlmostEquals(0, v.distanceToPoint(v));
      assertAlmostEquals(13, v.distanceToPoint(u));
      assertAlmostEquals(13, u.distanceToPoint(v));
      
      v = new Vector(3, -9);
      u = new Vector(-1, -6);
      assertAlmostEquals(5, v.distanceToPoint(u));
      assertAlmostEquals(5, u.distanceToPoint(v));
    };
    
    
    function testEquals() {
      var v = new Vector(-11, 0);      
      var u = new Vector(-11, 0);
      assertTrue(v.equals(v));
      assertTrue(v.equals(u));
      assertTrue(u.equals(v));
      
      u = new Vector(-10.99, 0.001);
      assertFalse(v.equals(u));
      assertFalse(u.equals(v));
      assertTrue('equality test with modified precision', v.equals(u, 0.1));
      assertTrue('equality test with modified precision', u.equals(v, 0.1));
      var precision = new geoPolygonUtils.geometry.Precision(1e-9, 0.1, 1e-9);
      assertTrue('equality test with custom Precision object',
                 v.equals(u, precision));
      assertTrue('equality test with custom Precision object',
                 u.equals(v, precision));
    };
    
    
    function testPointAlias() {
      var Point = geoPolygonUtils.geometry.Point;
      var p = new Point(3, -1);
      assertVectorCoords(3, -1, p);
      assertAlmostEquals(3, p.distanceToPoint(new Point(0, -1)));
    };
    
  </script>
  <style>
    .code {
      color: green;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <h1>Test Page for <span class="code">geoPolygonUtils.geometry.Vector</span>
  class.</h1>
  <p>This page contains tests for the methods of <span class="code">
  geoPolygonUtils.geometry.Vector</span> class. To see them take a look at the
  source of the page.</p>
  <p><em>Note:</em> this file is intended to be used with
  <a href="http://www.jsunit.net/">JSUnit</a> test framework.</p>
</body>
</html>
